package org.jsola.hr.service.impl;

import org.apache.commons.lang3.StringUtils;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.IEmpSocDispatchDAO;
import org.jsola.hr.dto.EmpSocDispatchAddDTO;
import org.jsola.hr.dto.EmpSocDispatchUpdateDTO;
import org.jsola.hr.entity.EmpInfoDO;
import org.jsola.hr.entity.EmpSocDispatchDO;
import org.jsola.hr.entity.SocDispatchEmpLessDO;
import org.jsola.hr.query.EmpSocDispatchQuery;
import org.jsola.hr.service.IEmpInfoService;
import org.jsola.hr.service.IEmpSocDispatchService;
import org.jsola.hr.vo.EmpSocDispatchListVO;
import org.jsola.hr.vo.EmpSocDispatchVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 员工社保派单状态表
 *
 * @author zhr
 */
@Service("hrEmpSocDispatchServiceImpl")
public class EmpSocDispatchServiceImpl implements IEmpSocDispatchService {

    @Autowired
    private IEmpSocDispatchDAO empSocDispatchDAO;

    @Autowired
    private IEmpInfoService empInfoService;

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpSocDispatchVO save(EmpSocDispatchAddDTO empSocDispatchAddDTO, TokenUser tokenUser) {
        // 转DO
        EmpSocDispatchDO empSocDispatchDO = empSocDispatchAddDTO.to(EmpSocDispatchDO.class);
        // 保存
        empSocDispatchDO = save(empSocDispatchDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return empSocDispatchDO.to(EmpSocDispatchVO.class);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(EmpSocDispatchUpdateDTO empSocDispatchUpdateDTO, TokenUser tokenUser) {
        //转DO
        EmpSocDispatchDO empSocDispatchDO = empSocDispatchUpdateDTO.to(EmpSocDispatchDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(empSocDispatchDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... empSocDispatchIds) {
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) empSocDispatchIds);
    }


    @Override
    public EmpSocDispatchVO selectById(String empSocDispatchId, String siteId) {
        EmpSocDispatchDO empSocDispatchDO = selectDOById(empSocDispatchId, siteId);
        if (empSocDispatchDO == null) {
            return null;
        }
        return empSocDispatchDO.to(EmpSocDispatchVO.class);
    }

    @Override
    public List<EmpSocDispatchListVO> select(EmpSocDispatchQuery empSocDispatchQuery, String siteId) {
        List<EmpSocDispatchDO> empSocDispatchDOList = selectDO(empSocDispatchQuery, siteId);
        if(CollectionUtils.isEmpty(empSocDispatchDOList)) {
            return empSocDispatchDOList == null ? null : new ArrayList<>();
        }
        return empSocDispatchDOList.stream()
                .map(empSocDispatchDO -> empSocDispatchDO.to(EmpSocDispatchListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(EmpSocDispatchQuery empSocDispatchQuery, String siteId) {
        Example example = buildExample(empSocDispatchQuery,siteId);
        return empSocDispatchDAO.selectCountByExample(example);
    }

    @Override
    public Page<EmpSocDispatchListVO> selectPage(EmpSocDispatchQuery empSocDispatchQuery, String siteId) {
        Example example = buildExample(empSocDispatchQuery,siteId);
        Page<EmpSocDispatchDO> page = empSocDispatchDAO.selectPageByExample(example,
                empSocDispatchQuery.getPageNo(),
                empSocDispatchQuery.getPageSize());

        return page.to(EmpSocDispatchListVO.class);
    }

    @Override
    public EmpSocDispatchDO selectDOById(String empSocDispatchId, String siteId) {
        return listById(empSocDispatchId, siteId);
    }

    @Override
    public List<EmpSocDispatchDO> selectDO(EmpSocDispatchQuery empSocDispatchQuery, String siteId) {
        Example example = buildExample(empSocDispatchQuery,siteId);
        return empSocDispatchDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void batchSave(List<EmpSocDispatchDO> empSocDispatchList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(empSocDispatchList)) {
            return;
        }
        empSocDispatchList.parallelStream().forEach(
                empSoc -> {
                    empSoc.preInsert(tokenUser.getUserId());
                    empSoc.setSiteId(tokenUser.getSiteId());
                }
        );
        empSocDispatchDAO.insertListAndSetId(empSocDispatchList);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void addByEmp(String empId, String progId, String companyId, TokenUser tokenUser) {
        EmpInfoDO empInfoDO = empInfoService.selectDOById(empId, tokenUser.getSiteId());
        if (Objects.isNull(empInfoDO)
                || StringUtils.isEmpty(empInfoDO.getIdCard())
                || !companyId.equals(empInfoDO.getCompanyId())) {
            return;
        }
        // 保存
        EmpSocDispatchAddDTO socDispatchAddDTO = new EmpSocDispatchAddDTO();
        socDispatchAddDTO.setName(empInfoDO.getName());
        socDispatchAddDTO.setPhone(empInfoDO.getPhone());
        socDispatchAddDTO.setIdCard(empInfoDO.getIdCard());
        socDispatchAddDTO.setCompanyId(empInfoDO.getCompanyId());
        socDispatchAddDTO.setSocProgId(progId);
        socDispatchAddDTO.setSocStartDate(new Date());
        socDispatchAddDTO.setFundStartDate(new Date());
        save(socDispatchAddDTO, tokenUser);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void endEmpSocByLess(List<SocDispatchEmpLessDO> empLessList, TokenUser tokenUser) {
        empLessList.parallelStream().forEach(
                empLess -> {
                    // 停保
                    Example example = new Example(EmpSocDispatchDO.class);
                    example.and()
                            .andEqualTo("companyId", empLess.getCompanyId())
                            .andEqualTo("idCard", empLess.getIdCard())
                            .andEqualTo("isHasLess", false)
                            .andEqualTo("valid", true)
                            .andEqualTo("siteId", tokenUser.getSiteId());

                    // 减员信息
                    EmpSocDispatchDO empSocUp = new EmpSocDispatchDO();
                    empSocUp.setSocDispatchEmpLessId(empLess.getId());
                    empSocUp.setSocEndDate(empLess.getSocEndDate());
                    empSocUp.setFundEndDate(empLess.getFundEndDate());
                    empSocUp.setIsHasLess(true);
                    empSocUp.setStatus(1);
                    empSocUp.preUpdate(tokenUser.getUserId());
                    // 修改信息
                    empSocDispatchDAO.updateByExampleSelective(empSocUp, example);
                }
        );
    }

    @Override
    public List<EmpSocDispatchDO> listEmpSocDispatchByIdCard(String companyId, String idCard, Boolean isHasLess, String siteId) {
        Example example = new Example(EmpSocDispatchDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("idCard", idCard)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        if (isHasLess != null) {
            example.and().andEqualTo("isHasLess", isHasLess);
        }
        example.orderBy("gmtCreate");
        return empSocDispatchDAO.selectByExample(example);
    }

    @Override
    public List<EmpSocDispatchDO> listEmpSocDispatchByIdCardList(String companyId, List<String> idCardList, String siteId) {
        if (CollectionUtils.isEmpty(idCardList)) {
            return null;
        }
        Example example = new Example(EmpSocDispatchDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("isHasLess", false)
                .andIn("idCard", idCardList)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        return empSocDispatchDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void deleteBySocDispatchEmpAddIds(String siteId, String... dispatchEmpAddIdList) {
        if (dispatchEmpAddIdList == null || dispatchEmpAddIdList.length == 0) {
            return;
        }
        Example example = new Example(EmpSocDispatchDO.class);
        example.and()
                .andIn("socDispatchEmpAddId", Arrays.asList(dispatchEmpAddIdList))
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        empSocDispatchDAO.deleteByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void stopEmpSoc(String companyId, String idCard, TokenUser tokenUser) {
        ParamException.hasLength(companyId, "员工停保,公司id不能为空");
        ParamException.hasLength(idCard, "请传递要停保的员工id");

        EmpInfoDO empInfoDO = empInfoService.selectDOById(idCard, tokenUser.getSiteId());
        if (Objects.nonNull(empInfoDO) && StringUtils.isNotEmpty(empInfoDO.getIdCard())) {
            idCard = empInfoDO.getIdCard();
        }

        Example example = new Example(EmpSocDispatchDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("idCard", idCard)
                .andEqualTo("isHasLess", false)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());

        // 减员信息
        EmpSocDispatchDO empSocUp = new EmpSocDispatchDO();
        empSocUp.setSocEndDate(new Date());
        empSocUp.setFundEndDate(new Date());
        empSocUp.setIsHasLess(true);
        empSocUp.setStatus(1);
        empSocUp.preUpdate(tokenUser.getUserId());
        // 修改信息
        empSocDispatchDAO.updateByExampleSelective(empSocUp, example);
    }


    /**
     * 根据查询参数，构建example

     * @param empSocDispatchQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(EmpSocDispatchQuery empSocDispatchQuery, String siteId) {
        Example example = new Example(EmpSocDispatchDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (empSocDispatchQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", empSocDispatchQuery.getCompanyId());
        }
        if (empSocDispatchQuery.getChildCompanyId() != null) {
            example.and().andEqualTo("childCompanyId", empSocDispatchQuery.getChildCompanyId());
        }
        if (empSocDispatchQuery.getName() != null) {
            example.and().andEqualTo("name", empSocDispatchQuery.getName());
        }
        if (empSocDispatchQuery.getPhone() != null) {
            example.and().andEqualTo("phone", empSocDispatchQuery.getPhone());
        }
        if (empSocDispatchQuery.getIdCard() != null) {
            example.and().andEqualTo("idCard", empSocDispatchQuery.getIdCard());
        }
        if (empSocDispatchQuery.getSocDispatchEmpAddId() != null) {
            example.and().andEqualTo("socDispatchEmpAddId", empSocDispatchQuery.getSocDispatchEmpAddId());
        }
        if (empSocDispatchQuery.getSocProgId() != null) {
            example.and().andEqualTo("socProgId", empSocDispatchQuery.getSocProgId());
        }
        if (empSocDispatchQuery.getSocStartDateStart() != null &&
                empSocDispatchQuery.getSocStartDateEnd() != null) {
            example.and().andBetween("socStartDate", empSocDispatchQuery.getSocStartDateStart(),
                    empSocDispatchQuery.getSocStartDateEnd());
        }
        if (empSocDispatchQuery.getFundStartDateStart() != null &&
                empSocDispatchQuery.getFundStartDateEnd() != null) {
            example.and().andBetween("fundStartDate", empSocDispatchQuery.getFundStartDateStart(),
                    empSocDispatchQuery.getFundStartDateEnd());
        }
        if (empSocDispatchQuery.getSocDispatchEmpLessId() != null) {
            example.and().andEqualTo("socDispatchEmpLessId", empSocDispatchQuery.getSocDispatchEmpLessId());
        }
        if (empSocDispatchQuery.getSocEndDateStart() != null &&
                empSocDispatchQuery.getSocEndDateEnd() != null) {
            example.and().andBetween("socEndDate", empSocDispatchQuery.getSocEndDateStart(),
                    empSocDispatchQuery.getSocEndDateEnd());
        }
        if (empSocDispatchQuery.getFundEndDateStart() != null &&
                empSocDispatchQuery.getFundEndDateEnd() != null) {
            example.and().andBetween("fundEndDate", empSocDispatchQuery.getFundEndDateStart(),
                    empSocDispatchQuery.getFundEndDateEnd());
        }
        if (empSocDispatchQuery.getIsHasLess() != null) {
            example.and().andEqualTo("isHasLess", empSocDispatchQuery.getIsHasLess());
        }
        if (empSocDispatchQuery.getStatus() != null) {
            example.and().andEqualTo("status", empSocDispatchQuery.getStatus());
        }
        // 排序
        ExampleKit.setExampleOrder(example,empSocDispatchQuery.getOrders());
        return example;
    }
}




